#pragma once
#include <vector>

#include "GaussSolver.h"
#include "LinerEquation.h"
#ifndef CURVEFITTING
#define CURVEFITTING

class CurveFitting
{
private:
	int n;
	double *c, *y;
	std::vector<double> res;

	auto calSquare( const int& m ) const -> double
	{
		if (!m)
		{
			return n;
		}
		double sum = 0;
		for (int i = 0; i < n; ++i)
		{
			sum += pow(c[i], m);
		}
		return sum;
	}

	auto calrVector( const int& m ) const -> double
	{
		double sum = 0;
		for (int i = 0; i < n; ++i)
		{
			sum += pow(c[i], m) * y[i];
		}
		return sum;
	}

public:
	CurveFitting( const double* c, const double* y, const int& n ) : n(n), c(new double[n]), y(new double[n])
	{
		for (int i = 0; i < n; ++i)
		{
			this->c[i] = c[i];
			this->y[i] = y[i];
		}
	}

	~CurveFitting()
	{
		delete[]c;
		delete[]y;
	}

	auto operator()( const int& m ) -> void
	{
		const auto rVector = new double[m + 1];
		const auto square = new double *[m + 1];
		for (int i = 0; i <= m; ++i)
		{
			square[i] = new double[m + 1];
			for (int j = 0; j < m; ++j)
			{
				if (i)
				{
					square[i][j] = square[i - 1][j + 1];
				}
				else
				{
					square[i][j] = calSquare(j);
				}
			}
			square[i][m] = calSquare(m + i);
			rVector[i] = calrVector(i);
		}
		LinerEquation temp(square, rVector, m + 1);
		for (int i = 0; i < m + 1; ++i)
		{
			delete[]square[i];
		}
		delete[]square;
		delete[]rVector;

		solver(temp);
		res.clear();
		for (int i = 0; i <= m; ++i)
		{
			res.emplace_back(temp.getAnsOf(i));
		}
	}

	auto getSize() const -> int
	{
		return res.size();
	}

	auto getResOf( const int& N ) const -> double
	{
		return res.at(N);
	}

	auto getRes()const ->std::vector<double>
	{
		return res;
	}
};

#endif
